//
// Created by Administrator on 2020/11/11.
//

#include "../include/uemApi.h"
#include "ueFsm.h"

int32_t UE_L3_UEM_Init(void)
{
    int32_t rc;

    rc = UE_L3_UE_SM_Init();
    IF_RETURN(!=, O5G_RC_OK, rc, O5G_RC_ER, "UE_L3_UEM_Init() UE_L3_UE_SM_Init() error!\n");

    return O5G_RC_OK;
}

int32_t UE_L3_UEM_Final(void)
{
    int32_t rc;

    rc = UE_L3_UE_SM_Final();
    IF_RETURN(!=, O5G_RC_OK, rc, O5G_RC_ER, "UE_L3_UEM_Final() UE_L3_UE_SM_Final() error!\n");

    return O5G_RC_OK;
}

void UE_L3_UEM_IndProcess(S_OsSelectInd *pIndMsg)
{
    switch (pIndMsg->ind)
    {
    case UE_L3_INTRA_IND_MSG_UE_FSM_EVT:
        UE_L3_UE_SM_IndProcess(pIndMsg);
        break;
    default:
        break;
    }
}

void UE_L3_UEM_MsgProcess(S_UeCommMsgHdr *pCommMsgHdr)
{
    uint32_t ueIdx;
    S_UeL3UeInst *pUeInst;
    S_FsmEventContext evtCtxt;
    S_OsSelectInd indMsg;

    switch (pCommMsgHdr->type)
    {
    case UE_L1_API_MSG_CONFIG_RSP:
        CSP_LOG_INF(UE_MD_L3_COMM, "UE_L3_UEM_MsgProcess() recv UE_L1_API_MSG_CONFIG_RSP\n");

        ueIdx = ((S_UeL1ApiMsgConfigRsp *)pCommMsgHdr)->ueIdx;
        pUeInst = &gpUeL3Context->ueInst[ueIdx];

        evtCtxt.event = UE_L3_UE_SM_EVENT_RECV_L1_CONFIG_RSP;
        evtCtxt.context = pUeInst;
        FixRB_Put(gpUeL3Context->ueFsmEvtQue, &evtCtxt, sizeof(evtCtxt));
        break;
    case UE_L1_API_MSG_SYNC_RSP:
        CSP_LOG_INF(UE_MD_L3_COMM, "UE_L3_UEM_MsgProcess() recv UE_L1_API_MSG_SYNC_RSP\n");

        ueIdx = ((S_UeL1ApiMsgConfigRsp *)pCommMsgHdr)->ueIdx;
        pUeInst = &gpUeL3Context->ueInst[ueIdx];

        evtCtxt.event = UE_L3_UE_SM_EVENT_RECV_L1_SYNC_RSP;
        evtCtxt.context = pUeInst;
        FixRB_Put(gpUeL3Context->ueFsmEvtQue, &evtCtxt, sizeof(evtCtxt));
        break;
    case UE_L2_L3_MSG_CONFIG_RSP:
        CSP_LOG_INF(UE_MD_L3_COMM, "UE_L3_UEM_MsgProcess() recv UE_L2_L3_MSG_CONFIG_RSP\n");

        ueIdx = ((S_UeL2L3MsgConfigRsp *)pCommMsgHdr)->ueIdx;
        pUeInst = &gpUeL3Context->ueInst[ueIdx];

        evtCtxt.event = UE_L3_UE_SM_EVENT_RECV_L2_CONFIG_RSP;
        evtCtxt.context = pUeInst;
        FixRB_Put(gpUeL3Context->ueFsmEvtQue, &evtCtxt, sizeof(evtCtxt));
        break;
    case UE_L2_L3_MSG_START_RSP:
        CSP_LOG_INF(UE_MD_L3_COMM, "UE_L3_UEM_MsgProcess() recv UE_L2_L3_MSG_START_RSP\n");

        ueIdx = ((S_UeL2L3MsgStartRsp *)pCommMsgHdr)->ueIdx;
        pUeInst = &gpUeL3Context->ueInst[ueIdx];

        evtCtxt.event = UE_L3_UE_SM_EVENT_RECV_L2_START_RSP;
        evtCtxt.context = pUeInst;
        FixRB_Put(gpUeL3Context->ueFsmEvtQue, &evtCtxt, sizeof(evtCtxt));
        break;
    default:
        CSP_LOG_WRN(UE_MD_L3_COMM, "UE_L3_CELLM_MsgProcess() recv unsupport msg[%#x]\n", pCommMsgHdr->type);
        break;
    }

    indMsg.ind = UE_L3_INTRA_IND_MSG_UE_FSM_EVT;
    OS_SelectSend(&gpUeL3Context->selector, &indMsg);
}

void UE_L3_UEM_PrdProcess(void)
{
    uint32_t ueLoop;
    uint32_t needSendInd;
    S_UeL3UeInst *pUeInst;
    S_FsmEventContext evtCtxt;
    S_OsSelectInd indMsg;

    needSendInd = FALSE;

    if (0 != gpUeL3Context->tick10ms % 10)
    {
        return;
    }

    for (ueLoop = 0; ueLoop < UE_UE_INST_NUM_MAX; ueLoop++)
    {
        pUeInst = &gpUeL3Context->ueInst[ueLoop];
        IF_CONTINUE(==, FALSE, pUeInst->inUse, NO_LOG_MESSAGE);

        if (UE_L3_UE_SM_STATE_INIT != FSM_INST_GetState(pUeInst->ueSmInst))
        {
            continue;
        }
        evtCtxt.event = UE_L3_UE_SM_EVENT_CELL_SEARCH_TRIGGER;
        evtCtxt.context = pUeInst;

        FixRB_Put(gpUeL3Context->ueFsmEvtQue, &evtCtxt, sizeof(evtCtxt));
        needSendInd = TRUE;
    }

    if (needSendInd)
    {
        indMsg.ind = UE_L3_INTRA_IND_MSG_UE_FSM_EVT;
        OS_SelectSend(&gpUeL3Context->selector, &indMsg);
    }
}

